package com.easymin.weixin.common.api;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.easymin.weixin.common.SignHelper;
import com.easymin.weixin.controller.v4.ResultTransport;
import com.easymin.weixin.entity.passenger.Passenger;
import com.easymin.weixin.entity.passenger.PassengerAddress;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.web.client.HttpClientErrorException;
import org.springframework.web.client.RestTemplate;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Created by shine on 15/9/28.
 */
@Component
public class PassengerApi {
  
  private static final Logger logger = LoggerFactory.getLogger(PassengerApi.class);

  @Value("${module.passenger.url}")
  private String passengerApiGateway;

  @Value("${module.passenger.appId}")
  private String passengerAppId;

  @Value("${module.passenger.appKey}")
  private String passengerAppKey;

  @Autowired
  private RestTemplate restTemplate;

  /**
   * 根据手机号查询一个客户.
   */
  public static final String FIND_ONE_API = "api/passengers/findone.json";
  /**
   * 根据id查询单个用户.
   */
  public static final String ONE_PASSENGER = "api/passengers/";
  /**
   * 查询单个客户的常用目的地.
   */
  public static final String QUERY_ADDRESS =
      "api/passengers/queryAddress.json?passengerId={passengerId}&appKey={appKey}"
      + "&appId={appId}&sign={sign}";
  /**
   * 保存客户常用目的地.
   */
  public static final String SAVE_ADDRESS = "api/passengers/";
  /**
   * 移除客户常用目的地.
   */
  public static final String REMOVE_ADDRESS = "api/passengers/";
  /**
   * 创建乘客接口.
   */
  public static final String CREATE = "api/passengers.json";
  /**
   * V4查询单个乘客.
   */
  public static final String FIND_ONE_V4 = "api/passengers/v4/findone.json";
  /**
   * V4创建乘客.
   */
  public static final String CREATE_V4 = "api/passengers/v4/create.json";

  /**
   * 根据手机号查询乘客信息.
   */
  public Passenger findOne(String phone, String appKey) {

    Map<String, String> kv = new HashMap<String, String>();

    kv.put("phone", phone);
    kv.put("appKey", appKey);
    kv.put("appId", passengerAppId);
    kv.put("ignoreYuyueAndBudan", Boolean.TRUE.toString());
    String sign = SignHelper.sign(SignHelper.buildSignMessage(kv), passengerAppKey);
    kv.put("sign", sign);

    StringBuilder builder = new StringBuilder();
    builder.append(buildApi(FIND_ONE_API));
    builder.append("?phone={phone}&appKey={appKey}&appId={appId}&sign={sign}");

    String response = restTemplate.getForObject(builder.toString(), String.class, kv);

    JSONObject jsonObject = JSON.parseObject(response);

    Passenger passenger = jsonObject.getObject("data", Passenger.class);

    return passenger;

  }
  
  /**
   * 根据电话号码查询乘客.
   */
  
  public ResultTransport findOneV4(String phone, String appKey) {

    Map<String, String> kv = new HashMap<String, String>();

    kv.put("phone", phone);
    kv.put("appKey", appKey);
    kv.put("appId", passengerAppId);
    String sign = SignHelper.sign(SignHelper.buildSignMessage(kv), passengerAppKey);
    kv.put("sign", sign);

    StringBuilder builder = new StringBuilder();
    builder.append(buildApi(FIND_ONE_V4));
    builder.append("?phone={phone}&appKey={appKey}&appId={appId}&sign={sign}");

    String result = restTemplate.getForObject(builder.toString(), String.class, kv);

    ResultTransport transport = JSON.parseObject(result, ResultTransport.class);

    return transport;

  }

  /**
   * 根据乘客Id查询单个乘客.
   */
  public Passenger findById(Long passengerId, String appKey) {

    Map<String, String> kv = new HashMap<String, String>();

    kv.put("appKey", appKey);
    kv.put("appId", passengerAppId);
    String sign = SignHelper.sign(SignHelper.buildSignMessage(kv), passengerAppKey);
    kv.put("sign", sign);

    StringBuilder builder = new StringBuilder();
    builder.append(buildApi(ONE_PASSENGER));
    builder.append(passengerId);
    builder.append(".json?appKey={appKey}&appId={appId}&sign={sign}");
    Passenger passenger = null;
    try {
      String response = restTemplate.getForObject(builder.toString(), String.class, kv);
      JSONObject jsonObject = JSON.parseObject(response);
      passenger = jsonObject.getObject("data", Passenger.class);
    } catch (Exception ex) {
      logger.error(ex.getMessage());
    }


    return passenger;

  }
  
  /**
   * 根据乘客Id查询单个乘客.
   */
  public JSONObject findByPassengerId(Long passengerId, String appKey) {

    Map<String, String> kv = new HashMap<String, String>();
    kv.put("appKey", appKey);
    kv.put("appId", passengerAppId);
    String sign = SignHelper.sign(SignHelper.buildSignMessage(kv), passengerAppKey);
    kv.put("sign", sign);

    StringBuilder builder = new StringBuilder();
    builder.append(buildApi(ONE_PASSENGER));
    builder.append(passengerId);
    builder.append(".json?appKey={appKey}&appId={appId}&sign={sign}");
    JSONObject jsonObject = null;
    try {
      String response = restTemplate.getForObject(builder.toString(), String.class, kv);
      jsonObject = JSON.parseObject(response);
    } catch (Exception ex) {
      logger.error(ex.getMessage());
    }
    return jsonObject;

  }

  /**
   * 查询客户的常用地址.
   */
  public Map<String, Object> queryAddress(Long passengerId, String appKey) {
    Map<String, Object> map = new HashMap<String, Object>();

    Map<String, String> kv = new HashMap<String, String>();

    kv.put("passengerId", String.valueOf(passengerId));
    kv.put("appKey", appKey);
    kv.put("appId", passengerAppId);
    String sign = SignHelper.sign(SignHelper.buildSignMessage(kv), passengerAppKey);
    kv.put("sign", sign);
    String response = restTemplate.getForObject(buildApi(QUERY_ADDRESS), String.class, kv);
    JSONObject jsonObject = JSON.parseObject(response);
    int code = jsonObject.getInteger("code");
    List<PassengerAddress> list = new ArrayList<PassengerAddress>();
    if (code == 0) {
      JSONArray data = jsonObject.getJSONArray("data");
      list = JSON.parseArray(data.toString(), PassengerAddress.class);
      map.put("code", 0);
      map.put("msg", "成功");
      map.put("data", list);
    } else {
      map.put("code", -1);
      map.put("msg", "失败");
      map.put("data", null);
    }
    return map;
  }

  /**
   * 保存客户常用目的地.
   */
  public Map<String, Object> saveAddress(String address, String addressDetail, Double latitude,
      Double longitude, Integer type, Long passengerId, String appKey) {
    Map<String, Object> map = new HashMap<String, Object>();

    Map<String, String> kv = new HashMap<String, String>();
    StringBuilder builder = new StringBuilder();
    builder.append(buildApi(SAVE_ADDRESS));
    builder.append(passengerId);
    kv.put("address", address);
    kv.put("addressDetail", addressDetail);
    kv.put("latitude", String.valueOf(latitude));
    kv.put("longitude", String.valueOf(longitude));
    kv.put("type", String.valueOf(type));
    kv.put("appKey", appKey);
    kv.put("appId", passengerAppId);
    String sign = SignHelper.sign(SignHelper.buildSignMessage(kv), passengerAppKey);
    kv.put("sign", sign);
    builder.append("/addressbooks.json?address={address}&addressDetail={addressDetail}");
    builder.append("&appKey={appKey}&latitude={latitude}&longitude={longitude}");
    builder.append("&type={type}&appId={appId}&sign={sign}");

    String reponse = restTemplate.postForObject(builder.toString(), null, String.class, kv);

    JSONObject jsonObject = JSON.parseObject(reponse);

    if (jsonObject.getIntValue("code") == 0) {
      PassengerAddress passengerAddress = jsonObject.getObject("data", PassengerAddress.class);
      map.put("code", 0);
      map.put("msg", "成功");
      map.put("data", passengerAddress);
    } else {
      map.put("code", -1);
      map.put("msg", "失败");
    }
    return map;
  }

  /**
   * 移除客户的常用目的地.
   */
  public Map<String, Object> removeAddress(Long passengerId, Long addressId, String appKey) {
    Map<String, Object> map = new HashMap<String, Object>();
    StringBuilder builder = new StringBuilder();
    builder.append(buildApi(REMOVE_ADDRESS));
    builder.append(passengerId);
    builder.append("/addressbooks/");
    builder.append(addressId);
    
    Map<String, String> kv = new HashMap<String, String>();
    kv.put("appKey", appKey);
    kv.put("appId", passengerAppId);
    String sign = SignHelper.sign(SignHelper.buildSignMessage(kv), passengerAppKey);
    kv.put("sign", sign);
    builder.append("?appKey={appKey}&appId={appId}&sign={sign}");
    try {
      restTemplate.delete(builder.toString(), kv);
      map.put("code", 0);
      map.put("msg", "移除成功");
      map.put("data", null);
    } catch (HttpClientErrorException ex) {
      map.put("code", -1);
      map.put("msg", "移除失败");
    }

    return map;
  }
  
  /**
   * 创建客户.
   */
  
  public Passenger createPassenger(String phone, String name, Long companyId, String companyName,
      String channelName, String appKey) {
    StringBuilder builder = new StringBuilder();
    builder.append(buildApi(CREATE));
    builder.append("?appKey={appKey}&appId={appId}&sign={sign}&phone={phone}&name={name}");
    builder.append("&companyId={companyId}&companyName={companyName}&channel_name={channel_name}");
    Map<String, String> kv = new HashMap<String, String>();
    kv.put("phone", phone);
    if (StringUtils.isNotBlank(name)) {
      kv.put("name", name);
    } else {
      kv.put("name", "先生/女士");
    }
    kv.put("channel_name", channelName);
    kv.put("companyId", String.valueOf(companyId));
    kv.put("companyName", companyName);
    kv.put("appKey", appKey);
    kv.put("appId", passengerAppId);
    String sign = SignHelper.sign(SignHelper.buildSignMessage(kv), passengerAppKey);
    kv.put("sign", sign);

    String reponse = restTemplate.postForObject(builder.toString(), null, String.class, kv);

    JSONObject jsonObject = JSON.parseObject(reponse);

    if (jsonObject.getIntValue("code") == 0) {
      return jsonObject.getObject("data", Passenger.class);
    }
    return null;
  }
  
  /**
   * 创建乘客.
   */
  
  public ResultTransport createPassengerV4(String phone, String name, Long companyId,
      String companyName, String channelName, String appKey) {
    StringBuilder builder = new StringBuilder();
    builder.append(buildApi(CREATE_V4));
    builder.append("?appKey={appKey}&appId={appId}&sign={sign}&phone={phone}");
    builder.append("&name={name}&companyId={companyId}&companyName={companyName}");
    builder.append("&channel_name={channel_name}");
    Map<String, String> kv = new HashMap<String, String>();
    kv.put("phone", phone);
    if (StringUtils.isNotBlank(name)) {
      kv.put("name", name);
    } else {
      kv.put("name", "先生/女士");
    }
    kv.put("channel_name", channelName);
    kv.put("companyId", String.valueOf(companyId));
    kv.put("companyName", companyName);
    kv.put("appKey", appKey);
    kv.put("appId", passengerAppId);

    String sign = SignHelper.sign(SignHelper.buildSignMessage(kv), passengerAppKey);

    kv.put("sign", sign);

    String result = restTemplate.postForObject(builder.toString(), null, String.class, kv);

    ResultTransport transport = JSON.parseObject(result, ResultTransport.class);

    return transport;
  }
  
  /**
   * 创建乘客.
   */
  
  public JSONObject createPassengerV4New(String phone, String name, Long companyId,
      String companyName, String channelName, String appKey) {
    StringBuilder builder = new StringBuilder();
    builder.append(buildApi(CREATE_V4));
    builder.append("?appKey={appKey}&appId={appId}&sign={sign}&phone={phone}");
    builder.append("&name={name}&companyId={companyId}");
    builder.append("&companyName={companyName}&channel_name={channel_name}");
    
    Map<String, String> kv = new HashMap<String, String>();
    kv.put("phone", phone);
    if (StringUtils.isNotBlank(name)) {
      kv.put("name", name);
    } else {
      kv.put("name", "先生/女士");
    }
    kv.put("channel_name", channelName);
    kv.put("companyId", String.valueOf(companyId));
    kv.put("companyName", companyName);
    kv.put("appKey", appKey);
    kv.put("appId", passengerAppId);

    String sign = SignHelper.sign(SignHelper.buildSignMessage(kv), passengerAppKey);

    kv.put("sign", sign);

    String result = restTemplate.postForObject(builder.toString(), null, String.class, kv);

    JSONObject jsonObject = JSON.parseObject(result);

    return jsonObject;
  }


  /**
   * 创建乘客信息.
   */
  public Passenger create(Passenger passenger, String appKey) {

    StringBuilder sb = new StringBuilder();
    sb.append(buildApi(CREATE));
    sb.append("?appKey={appKey}&appId={appId}&sign={sign}");
    sb.append("&phone={phone}&companyId={companyId}&companyName={companyName}");
    sb.append("&idcard={idcard}");
    sb.append("&email={email}");
    sb.append("&name={name}");
    sb.append("&channel_name={channel_name}");
    sb.append("&address={address}");
    sb.append("&plateNumber={plateNumber}");
    sb.append("&memo={memo}");
    sb.append("&allowOverdraw={allowOverdraw}");
    sb.append("&gender={gender}");
    sb.append("&grade_id={grade_id}");

    Map<String, String> kv = new HashMap<String, String>();
    kv.put("phone", passenger.getPhone());
    kv.put("companyId", String.valueOf(passenger.getCompanyId()));
    kv.put("companyName", passenger.getCompanyName());
    kv.put("idcard", passenger.getIdcard());
    kv.put("email", passenger.getEmail());
    kv.put("name", passenger.getName());
    kv.put("channel_name", passenger.getChannel_name());
    kv.put("address", passenger.getAddress());
    kv.put("plateNumber", passenger.getPlateNumber());
    kv.put("memo", passenger.getMemo());
    kv.put("allowOverdraw", String.valueOf(passenger.getAllowOverdraw()));
    kv.put("gender", passenger.getGender() == null ? "0" : String.valueOf(passenger.getGender()));
    kv.put("grade_id",
        passenger.getGrade_id() == null ? null : String.valueOf(passenger.getGrade_id()));
    kv.put("appKey", appKey);
    kv.put("appId", passengerAppId);
    String sign = SignHelper.sign(SignHelper.buildSignMessage(kv), passengerAppKey);
    kv.put("sign", sign);

    String reponse = restTemplate.postForObject(sb.toString(), null, String.class, kv);

    JSONObject jsonObject = JSON.parseObject(reponse);

    if (jsonObject.getIntValue("code") == 0) {

      return jsonObject.getObject("data", Passenger.class);
    }

    return null;
  }

  private String buildApi(String api) {

    StringBuilder builder = new StringBuilder();
    builder.append(passengerApiGateway);
    if (!passengerApiGateway.endsWith("/")) {
      builder.append("/");
    }
    builder.append(api);

    return builder.toString();
  }
  
}
